package com.bole.service.impl;

import com.bole.config.ElasticSearchConfig;
import com.bole.dto.car.EsCar;
import com.bole.dto.car.Page;
import com.bole.dto.car.TbCarDto;
import com.bole.feign.CarFeign;
import com.bole.service.EsService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
public class EsServiceImpl implements EsService {

    @Autowired
    private CarFeign carFeign;

    @Autowired
    private RestHighLevelClient restHighLevelClient;

    @Override
    public void insertElasticsearchIndex(Long[] ids) {
        IndexRequest request = new IndexRequest("bole_es", "car");
        EsCar esCar = new EsCar();
        for (Long id : ids) {
            TbCarDto carDto = carFeign.getCarById(id);
            try {
                request.id(carDto.getId().toString());
                esCar.setId(carDto.getId());
                esCar.setName(carDto.getName());
                esCar.setTitle(carDto.getTitle());
                esCar.setLenLat(carDto.getLenLat());
                esCar.setPrice(carDto.getPrice());
                esCar.setBrandId(carDto.getBrandId());
                esCar.setCarSeriesId(carDto.getCarSeriesId());
                esCar.setDetailsId(carDto.getDetailsId());
                esCar.setStatus(carDto.getStatus());
                esCar.setDetailsId(carDto.getDetailsId());
                esCar.setSellUserId(carDto.getSellUserId());
                esCar.setSellPhone(carDto.getSellPhone());
                esCar.setUrl(carDto.getUrl());
                String userJson = new ObjectMapper().writeValueAsString(esCar);
                request.source(userJson, XContentType.JSON);
                //执行操作
                IndexResponse response = restHighLevelClient.index(request, ElasticSearchConfig.COMMON_OPTIONS);
                //提取有用的响应信息
                System.out.println(">>>index: " + response);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public Page listSearchByName(Integer pageNum, Integer pageSize, String searchName) {
        Page page = new Page();
        page.setPageNum(pageNum);
        page.setPageSize(pageSize);


        // 创建检索请求
        SearchRequest searchRequest = new SearchRequest();
        //指定DSL检索条件
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        MatchPhraseQueryBuilder mpq1 = QueryBuilders
                .matchPhraseQuery("title",searchName);
        MatchPhraseQueryBuilder mpq3 = QueryBuilders
                .matchPhraseQuery("status",1);
        //.matchPhraseQuery("detailsId",detailsId);
        QueryBuilder qb2 = QueryBuilders.boolQuery().must(mpq1).must(mpq3);
        searchSourceBuilder.query(qb2);
        searchRequest.source(searchSourceBuilder);

        try {
            // 不分页的总条数
            SearchResponse search = restHighLevelClient.search(searchRequest, ElasticSearchConfig.COMMON_OPTIONS);
            Long totalHitsCount = search.getHits().getTotalHits();
            page.setTotalCount(totalHitsCount.intValue());
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 分页查询
        searchSourceBuilder.from(pageNum);
        searchSourceBuilder.size(pageSize);

        // 高亮
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("title");// 高亮的字段
        highlightBuilder.requireFieldMatch(false);// 是否多个字段都高亮
        highlightBuilder.preTags("<span style='color:red'>");// 前缀后缀
        highlightBuilder.postTags("</span>");
        searchSourceBuilder.highlighter(highlightBuilder);

        System.out.println(">>>检索条件 : "+searchSourceBuilder);

        searchRequest.source(searchSourceBuilder);
        //执行检索
        try {
            SearchResponse search = restHighLevelClient.search(searchRequest, ElasticSearchConfig.COMMON_OPTIONS);
            //分析结果
            System.out.println(">>>返回结果"+search.toString());
            SearchHits hits = search.getHits();
            SearchHit[] innerHis = hits.getHits();
            List<Map<String, Object>> searchList = new ArrayList<>();
            for (SearchHit hit : innerHis) {
                // 解析高亮的字段
                // 获取高亮字段
                Map<String, HighlightField> highlightFields = hit.getHighlightFields();
                // System.out.println("=========="+highlightFields);
                HighlightField title = highlightFields.get("title");
                // System.out.println("==content=="+content);
                Map<String, Object> sourceAsMap = hit.getSourceAsMap();// 原来的结果
                //将原来的字段替换为高亮字段即可
                if (title != null){
                    Text[] fragments = title.fragments();
                    String newTitle = "";
                    for (Text text : fragments) {
                        newTitle += text;
                    }
                    sourceAsMap.put("title", newTitle);// 替换掉原来的内容
                }
                searchList.add(sourceAsMap);
                // 结果集放入pageinfo
                page.setResult(searchList);
            }
            return  page;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    @Override
    public Page selectCarSeriesId(Integer pageNum, Integer pageSize, Long carSeriesId, String detailsId) {
        Page page = new Page();
        page.setPageNum(pageNum);
        page.setPageSize(pageSize);

        // 创建检索请求
        SearchRequest searchRequest = new SearchRequest();
        //指定索引
        searchRequest.indices("bole_es");
        //指定DSL检索条件
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        MatchPhraseQueryBuilder mpq1 = QueryBuilders
                .matchPhraseQuery("carSeriesId",carSeriesId);
        WildcardQueryBuilder mpq2 = QueryBuilders.wildcardQuery("detailsId","*"+detailsId+"*");
        MatchPhraseQueryBuilder mpq3 = QueryBuilders
                .matchPhraseQuery("status",1);
        //.matchPhraseQuery("detailsId",detailsId);
        QueryBuilder qb2 = QueryBuilders.boolQuery().must(mpq1).must(mpq2).must(mpq3);
        searchSourceBuilder.query(qb2);
        searchRequest.source(searchSourceBuilder);


        // 分页查询
        searchSourceBuilder.from(pageNum);
        searchSourceBuilder.size(pageSize);
        try {
            // 不分页的总条数
            SearchResponse search = restHighLevelClient.search(searchRequest, ElasticSearchConfig.COMMON_OPTIONS);
            Long totalHitsCount = search.getHits().getTotalHits();
            page.setTotalCount(totalHitsCount.intValue());
        } catch (IOException e) {
            e.printStackTrace();
        }


        // 高亮
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("carSeriesId");// 高亮的字段
        highlightBuilder.field("detailsId");// 高亮的字段
        highlightBuilder.requireFieldMatch(false);// 是否多个字段都高亮
        highlightBuilder.preTags("<span style='color:red'>");// 前缀后缀
        highlightBuilder.postTags("</span>");
        searchSourceBuilder.highlighter(highlightBuilder);

        System.out.println(">>>检索条件 : " + searchSourceBuilder);

        searchRequest.source(searchSourceBuilder);
        //执行检索
        try {
            SearchResponse search = restHighLevelClient.search(searchRequest, ElasticSearchConfig.COMMON_OPTIONS);
            //分析结果
            System.out.println(">>>返回结果" + search.toString());
            SearchHits hits = search.getHits();
            SearchHit[] innerHis = hits.getHits();
            List<Map<String, Object>> searchList = new ArrayList<>();
            for (SearchHit hit : innerHis) {
                // 解析高亮的字段
                // 获取高亮字段
                Map<String, HighlightField> highlightFields = hit.getHighlightFields();
                // System.out.println("=========="+highlightFields);
                HighlightField title = highlightFields.get("carSeriesId");
                // System.out.println("==content=="+content);
                Map<String, Object> sourceAsMap = hit.getSourceAsMap();// 原来的结果
                //将原来的字段替换为高亮字段即可
                if (title != null) {
                    Text[] fragments = title.fragments();
                    String newTitle = "";
                    for (Text text : fragments) {
                        newTitle += text;
                    }
                    sourceAsMap.put("carSeriesId", newTitle);// 替换掉原来的内容
                }
                searchList.add(sourceAsMap);
                // 结果集放入pageinfo
                page.setResult(searchList);
            }
            return page;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }


    @Override
    public void updateStatus(Long carId) {
        IndexRequest request = new IndexRequest("bole_es", "car");
        EsCar esCar = new EsCar();
        TbCarDto carDto = carFeign.getCarById(carId);
                request.id(carId.toString());
                esCar.setId(carDto.getId());
                esCar.setName(carDto.getName());
                esCar.setTitle(carDto.getTitle());
                esCar.setLenLat(carDto.getLenLat());
                esCar.setPrice(carDto.getPrice());
                esCar.setBrandId(carDto.getBrandId());
                esCar.setCarSeriesId(carDto.getCarSeriesId());
                esCar.setDetailsId(carDto.getDetailsId());
                esCar.setStatus(4);
                esCar.setDetailsId(carDto.getDetailsId());
                esCar.setSellUserId(carDto.getSellUserId());
                esCar.setSellPhone(carDto.getSellPhone());
                esCar.setUrl(carDto.getUrl());
        String userJson = null;
        try {
            userJson = new ObjectMapper().writeValueAsString(esCar);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        request.source(userJson, XContentType.JSON);
                //执行操作
        IndexResponse response = null;
        try {
            response = restHighLevelClient.index(request, ElasticSearchConfig.COMMON_OPTIONS);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //提取有用的响应信息
                System.out.println(">>>index: " + response);

        }
    }

